home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / IDE / SUBARTIC / SUB_ARCT / OUTPUT / SHADOW_D.JAV < prev    next >
Encoding:
Text File  |  1996-10-04  |  19.3 KB  |  557 lines

  1.  
  2. package sub_arctic.output;
  3.  
  4. import sub_arctic.lib.manager;
  5.  
  6. import java.awt.Graphics;
  7. import java.awt.Font;
  8. import java.awt.FontMetrics;
  9. import java.awt.Color;
  10. import java.awt.Rectangle;
  11. import java.awt.Polygon;
  12. import java.awt.Image;
  13. import java.awt.image.ImageObserver;
  14. import java.awt.image.ImageFilter;
  15. import java.awt.image.RGBImageFilter;
  16. import java.awt.image.ImageProducer;
  17. import java.awt.image.FilteredImageSource;
  18.  
  19. /** 
  20.  * A drawable object that draws everything in a uniform color 
  21.  * (typically a light gray) offset by a small amount.  This is used to 
  22.  * cast shadows by drawing objects once offset slightly in gray, then 
  23.  * again over the top in normal colors.  This drawable operates in two
  24.  * modes: expensive (but slow) or cheap (but fast).  In cheap mode, images
  25.  * are drawn as unicolor rectangles.  In expensive mode, we process images
  26.  * to properly account for transparency.
  27.  *
  28.  * @author Scott Hudson
  29.  */
  30. public class shadow_drawable extends drawable {
  31.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  32.  
  33.   /** Color we paint everything in */
  34.   protected Color the_color = null;
  35.  
  36.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  37.  
  38.   /** Filter to turn images into our one color */
  39.   protected ImageFilter   uni_filter;
  40.  
  41.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  42.  
  43.   /** Do we do expensive but realistic drawing of images, or do we just 
  44.    *  do their bounding rectangle?  Default is to be cheap about it.
  45.    */
  46.   protected boolean _expensive_draw = false;
  47.  
  48.   /** Are currently doing expensive but realistic drawing of images, or do 
  49.    *  are we just drawing their bounding rectangle?
  50.    */
  51.   public boolean expensive_draw() {return _expensive_draw;} 
  52.  
  53.   /** Set whether we draw images realistically, but expensively (slow),
  54.    *  or just draw their bounding rectangles (fast).
  55.    */
  56.   public void set_expensive_draw(boolean v) 
  57.     {
  58.       _expensive_draw = v;
  59.     }
  60.  
  61.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  62.  
  63.   /** 
  64.    * Full constructor.
  65.    * 
  66.    * @param Graphics wrappee           Graphics object we are a wrapper around.
  67.    * @param int      off_x             x offset we draw everything at.
  68.    * @param int      off_y             y offset we draw everything at.
  69.    * @param Color    c                 color we draw everything in.
  70.    * @param boolean  do_expensive_draw do we use expensive mode?
  71.    */
  72.   public shadow_drawable(
  73.     Graphics wrappee, 
  74.     int      off_x, 
  75.     int      off_y, 
  76.     Color    c, 
  77.     boolean  do_expensive_draw) 
  78.     {
  79.       /* let super class initialize based on a copy */
  80.       super(wrappee.create());
  81.  
  82.       /* apply a translation to the wrapped Graphics */
  83.       g.translate(off_x, off_y);
  84.  
  85.       /* apply and save the color */
  86.       g.setColor(c);
  87.       the_color = c;
  88.  
  89.       /* construct a filter for our color */
  90.       uni_filter = new unicolor_filter(the_color);
  91.  
  92.       /* remember how to draw */
  93.       _expensive_draw = do_expensive_draw;
  94.     }
  95.  
  96.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  97.  
  98.   /** 
  99.    * Constructor that defaults to fast drawing 
  100.    *
  101.    * @param Graphics wrappee Graphics object we are a wrapper around.
  102.    * @param int      off_x   x offset we draw everything at.
  103.    * @param int      off_y   y offset we draw everything at.
  104.    * @param Color    c       color we draw everything in.
  105.    */
  106.   public shadow_drawable(Graphics wrappee, int off_x, int off_y, Color c)
  107.     {
  108.       this(wrappee,off_x,off_y,c,false);
  109.     }
  110.  
  111.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  112.  
  113.   /** 
  114.    * Full constructor from a drawable 
  115.    *
  116.    * @param drawable wrappee           drawable object we are a wrapper around.
  117.    * @param int      off_x             x offset we draw everything at.
  118.    * @param int      off_y             y offset we draw everything at.
  119.    * @param Color    c                 color we draw everything in.
  120.    * @param boolean  do_expensive_draw do we use expensive mode?
  121.    */
  122.   public shadow_drawable(
  123.     drawable wrappee, 
  124.     int      off_x, 
  125.     int      off_y, 
  126.     Color    c, 
  127.     boolean  do_expensive_draw) 
  128.     {
  129.       /* let super class initialize based on a copy of the Graphics object */
  130.       super(wrappee.g.create());
  131.  
  132.       /* apply a translation to the wrapped Graphics */
  133.       g.translate(off_x, off_y);
  134.  
  135.       /* apply and save the color */
  136.       g.setColor(c);
  137.       the_color = c;
  138.  
  139.       /* construct a filter for our color */
  140.       uni_filter = new unicolor_filter(the_color);
  141.  
  142.       /* remember how to draw */
  143.       _expensive_draw = do_expensive_draw;
  144.     }
  145.  
  146.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  147.  
  148.   /** 
  149.    * Constructor from drawable that defaults to fast drawing 
  150.    * 
  151.    * @param drawable wrappee drawable object we are a wrapper around.
  152.    * @param int      off_x   x offset we draw everything at.
  153.    * @param int      off_y   offset we draw everything at.
  154.    * @param Color    c       color we draw everything in.
  155.    */
  156.   public shadow_drawable(drawable wrappee, int off_x, int off_y, Color c)
  157.     {
  158.       this(wrappee,off_x,off_y,c,false);
  159.     }
  160.  
  161.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  162.  
  163.   /** Default for x drawing offset (10). */
  164.   public static final int   default_off_x = 10;
  165.  
  166.   /** Default for y drawing offset (10). */
  167.   public static final int   default_off_y = 10;
  168.  
  169.   /** Default color for drawing (Color.gray). */
  170.   public static final Color default_color = Color.gray;
  171.  
  172.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  173.  
  174.   /** 
  175.    * Constructor with default color. 
  176.    *
  177.    * @param Graphics wrappee Graphics object we are a wrapper around.
  178.    * @param int      off_x   x offset we draw everything at.
  179.    * @param int      off_y   y offset we draw everything at.
  180.    */
  181.   public shadow_drawable(Graphics wrappee, int off_x, int off_y)
  182.     {
  183.       this(wrappee, off_x, off_y, default_color);
  184.     }
  185.  
  186.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  187.  
  188.   /** 
  189.    * Constructor with default shadow offset and color 
  190.    *
  191.    * @param Graphics wrappee Graphics object we are a wrapper around.
  192.    */
  193.   public shadow_drawable(Graphics wrappee)
  194.     {
  195.       this(wrappee, default_off_x, default_off_y, default_color);
  196.     }
  197.  
  198.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  199.  
  200.   /** 
  201.    * Override copy() to create a new wrapper also.
  202.    * @return drawable the new shadow_drawable object.
  203.    */
  204.   public drawable copy() 
  205.     {
  206.       /* create new wrapper, but don't add translation since g already has it */
  207.       return new shadow_drawable(g.create(), 0,0, the_color, expensive_draw());
  208.     }
  209.  
  210.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  211.  
  212.   /** 
  213.    * Override copy() to create a new wrapper also.
  214.    * @param int x x origin for new drawable.
  215.    * @param int y y origin for new drawable.
  216.    * @param int w width of new drawable.
  217.    * @param int h height of new drawable.
  218.    * @return drawable the new shadow_drawable object.
  219.    */
  220.   public drawable copy(int x, int y, int w, int h) 
  221.     {
  222.       /* create new wrapper, but don't add translation since g already has it */
  223.       return new shadow_drawable(g.create(x,y,w,h),0,0,the_color, 
  224.                              expensive_draw());
  225.     }
  226.  
  227.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  228.  
  229.   /**
  230.    * Override create() to create a new wrapper also. 
  231.    * @return Graphics new shadow_drawable object. 
  232.    */
  233.   public Graphics create() 
  234.     {
  235.       /* create new wrapper, but don't add translation since g already has it */
  236.       return new shadow_drawable(g.create(), 0,0, the_color, expensive_draw());
  237.     }
  238.  
  239.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  240.  
  241.   /** 
  242.    * Override create() to create a new wrapper also.
  243.    * @param int x x origin for new drawable.
  244.    * @param int y y origin for new drawable.
  245.    * @param int w width of new drawable.
  246.    * @param int h height of new drawable.
  247.    * @return Graphics the new shadow_drawable object.
  248.    */
  249.   public Graphics create(int x, int y, int w, int h) 
  250.     {
  251.       /* create new wrapper, but don't add translation since g already has it */
  252.       return new shadow_drawable(g.create(x,y,w,h),0,0,the_color, 
  253.                               expensive_draw());
  254.     }
  255.  
  256.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  257.  
  258.   /** 
  259.    * Override to set all colors to our color.
  260.    * @param Color c color we were supposed to draw in but don't.
  261.    */
  262.   public void setColor(Color c) {g.setColor(the_color);}
  263.  
  264.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  265.  
  266.   /** 
  267.    * Override to turn into a fill with our color.
  268.    *
  269.    * @param int x  source x position.
  270.    * @param int y  source y position.
  271.    * @param int w  width of copied area.
  272.    * @param int h  height of copied area.
  273.    * @param int dx destination x position.
  274.    * @param int dy destination y position.
  275.    */
  276.   public void copyArea(int x, int y, int w, int h, int dx, int dy)
  277.     {g.fillRect(dx,dy,w,h);}
  278.  
  279.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  280.  
  281.   /** 
  282.    * Override to turn clear into fill with our color (since clear is an 
  283.    * opaque operation). 
  284.    *
  285.    * @param int x x position of area to clear. 
  286.    * @param int y y position of area to clear. 
  287.    * @param int w width of area to clear. 
  288.    * @param int h height of area to clear. 
  289.    */
  290.   public void clearRect(int x, int y, int w, int h)
  291.     {g.fillRect(x,y,w,h);}
  292.  
  293.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  294.  
  295.   /** 
  296.    * Process an image to make a shadow version.  This is the expensive version
  297.    * of the operation.  Basically we turn all colors to our color, but leave
  298.    * the transparency (alpha) value alone.  This requires a pixel by pixel
  299.    * mapping, so it can be slow.
  300.    *
  301.    * @param Image from_img the image that we are filtering to produce a shadow
  302.    *                       version of.
  303.    */
  304.   protected Image make_shadow(Image from_img)
  305.     {
  306.       ImageProducer shadow_prod;
  307.       Image         result;
  308.  
  309.       shadow_prod = new FilteredImageSource(from_img.getSource(),uni_filter);
  310.       result = manager.default_toolkit().createImage(shadow_prod);
  311.       manager.wait_for_image(result);
  312.       return result;
  313.     }
  314.  
  315.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  316.  
  317.   /** 
  318.    * Override to filter images, turning all non-transparent colors to ours.
  319.    * This will do either the expensive version via make_shadow() or the
  320.    * cheap version that fills a rectangle depending on the setting of 
  321.    * expensive_draw.
  322.    *
  323.    * @param Image         img      the image to be drawn.
  324.    * @param int           x        x position to place the image at.
  325.    * @param int           y        y position to place the image at.
  326.    * @param ImageObserver observer observer to notify us of progress drawing 
  327.    *                               the Image
  328.    * @return boolean undocumented AWT return value (here we always return true).
  329.    */
  330.   public boolean drawImage(Image img, int x, int y, ImageObserver observer)
  331.     {
  332.       /* if we are set to do it right, but slow, do so */
  333.       if (expensive_draw())
  334.          return g.drawImage(make_shadow(img),x,y,observer);
  335.  
  336.       /* otherwise, fill area of image */
  337.       g.fillRect(x,y,img.getWidth(manager.an_observer()), 
  338.              img.getHeight(manager.an_observer()));
  339.  
  340.       /* There really isn't any documentation on what this return value 
  341.        *  is supposed to signify, but it appears to indicate that
  342.        *  the image in question was fully loaded and drawn without
  343.        *  error, so we can safely return true here.
  344.        */
  345.       return true;  
  346.     }
  347.  
  348.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  349.  
  350.   /** 
  351.    * Override to filter images, turning all non-transparent colors to ours.
  352.    * This will do either the expensive version via make_shadow() or the
  353.    * cheap version that fills a rectangle depending on the setting of 
  354.    * expensive_draw.
  355.    *
  356.    * @param Image         img      the image to be drawn.
  357.    * @param int           x        x position to place the image at.
  358.    * @param int           y        y position to place the image at.
  359.    * @param int           w        width that image will be scaled to.
  360.    * @param int           h        height that image will be scaled to.
  361.    * @param ImageObserver observer observer to notify us of progress drawing 
  362.    *                               the Image
  363.    * @return boolean undocumented AWT return value (here we always return true).
  364.    */
  365.   public boolean drawImage(Image img, int x, int y, int w, int h, 
  366.                                                           ImageObserver obs)
  367.     {
  368.       /* if we are set to do it right, but slow, do so */
  369.       if (expensive_draw())
  370.         return g.drawImage(make_shadow(img),x,y,w,h,obs);
  371.  
  372.       /* otherwise, fill area of image */
  373.       g.fillRect(x,y,w,h);
  374.       return true;
  375.     }
  376.  
  377.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  378.  
  379.   /** 
  380.    * Override to filter images, turning all non-transparent colors to ours.
  381.    * This will do either the expensive version via make_shadow() or the
  382.    * cheap version that fills a rectangle depending on the setting of 
  383.    * expensive_draw.
  384.    *
  385.    * @param Image         img      the image to be drawn.
  386.    * @param int           x        x position to place the image at.
  387.    * @param int           y        y position to place the image at.
  388.    * @param Color         bgcolor  background color.
  389.    * @param ImageObserver observer observer to notify us of progress drawing 
  390.    *                               the Image
  391.    * @return boolean undocumented AWT return value (here we always return true).
  392.    */
  393.   public boolean drawImage(Image img, int x, int y, Color bgcolor,
  394.                                           ImageObserver obs) 
  395.     {
  396.       /* if we are set to do it right, but slow, do so */
  397.       if (expensive_draw())
  398.         return g.drawImage(make_shadow(img),x,y,bgcolor,obs);
  399.  
  400.       /* otherwise, fill area of image */
  401.       g.fillRect(x,y,img.getWidth(manager.an_observer()), 
  402.              img.getHeight(manager.an_observer()));
  403.       return true;
  404.     }
  405.  
  406.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  407.  
  408.   /** 
  409.    * Override to filter images, turning all non-transparent colors to ours.
  410.    * This will do either the expensive version via make_shadow() or the
  411.    * cheap version that fills a rectangle depending on the setting of 
  412.    * expensive_draw.
  413.    *
  414.    * @param Image         img      the image to be drawn.
  415.    * @param int           x        x position to place the image at.
  416.    * @param int           y        y position to place the image at.
  417.    * @param int           w        width that image will be scaled to.
  418.    * @param int           h        height that image will be scaled to.
  419.    * @param Color         bgcolor  background color.
  420.    * @param ImageObserver observer observer to notify us of progress drawing 
  421.    *                               the Image
  422.    * @return boolean undocumented AWT return value (here we always return true).
  423.    */
  424.   public boolean drawImage(Image img, int x, int y, int w, int h, Color bgcolor,
  425.                                           ImageObserver obs)
  426.     {
  427.       /* if we are set to do it right, but slow, do so */
  428.       if (expensive_draw())
  429.         return g.drawImage(make_shadow(img),x,y,w,h,bgcolor,obs);
  430.  
  431.       /* otherwise, fill area of image */
  432.       g.fillRect(x,y,w,h);
  433.       return true;
  434.     }
  435.  
  436.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  437.  
  438.   /** 
  439.    * Override tiled image drawing, turning all non-transparent colors to ours. 
  440.    *
  441.    * @param loaded_image  pattern the pattern we tile with
  442.    * @param int           x        x position to place the image at.
  443.    * @param int           y        y position to place the image at.
  444.    * @param int           w        width of area to tile.
  445.    * @param int           h        height of area to tile.
  446.    * @return boolean undocumented AWT return value (here we always return true).
  447.    */
  448.   public boolean tileImage(loaded_image pattern, int x, int y, int w, int h)
  449.     {
  450.       Image img  = pattern.image();
  451.       int size_x = pattern.width();
  452.       int size_y = pattern.height();
  453.       int xpt, ypt;
  454.       Graphics clipped_g;
  455.       boolean v = true;
  456.  
  457.       /* if we are set to do it fast, just do a fill */ 
  458.       if (!expensive_draw())
  459.     {
  460.           g.fillRect(x,y,w,h);
  461.           return true;
  462.     }
  463.  
  464.       /* Build a shadow copy of the pattern */
  465.       Image shadow_pat = make_shadow(pattern.image());
  466.  
  467.       /* Build a copy of our Graphics object that clips to exactly the size
  468.        * we are clipping into 
  469.        */
  470.       clipped_g = g.create();
  471.       clipped_g.clipRect(x,y,w,h);
  472.  
  473.       /* loop over image area drawing tiles until we have filled it */
  474.       for (ypt = y; ypt-y < h; ypt += size_y)
  475.         for (xpt = x; xpt-x < w; xpt += size_x)
  476.       v = clipped_g.drawImage(shadow_pat, xpt, ypt, _ignore);
  477.  
  478.       /* return the last return value we got */
  479.       return v;
  480.     }
  481.  
  482.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  483. }
  484.  
  485. /*---------------------------------------------------------------------*/
  486.  
  487. /** 
  488.  * An image filter class to turn all non-transparent colors to one color. 
  489.  * This simply replaces the R, G, and B components of a color with our own,
  490.  * leaving the alpha (transparency) value alone.
  491.  *
  492.  * @see sub_arctic.output.shadow_drawable
  493.  * @author Scott Hudson
  494.  */
  495. class unicolor_filter extends RGBImageFilter {
  496.  
  497.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  498.  
  499.   /** Encoding for the color we turn everything into */
  500.   public int one_color;
  501.  
  502.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  503.  
  504.   /** 
  505.    * Constructor.
  506.    * @param Color c color that we turn everything to.
  507.    */
  508.   public unicolor_filter(Color c)
  509.     {
  510.       /* flag for the superclass */
  511.       canFilterIndexColorModel = true;
  512.  
  513.       /* encode our color in a 32 bit word. we set high order bits for alpha 
  514.        * to 00 here so we can easily add it later.
  515.        */
  516.       one_color = c.getRGB() & 0x00ffffff;
  517.     }
  518.  
  519.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  520.  
  521.   /** 
  522.    * The actual filter that processes every pixel.  Here we replace the RGB
  523.    * components with our one color, but leave the transparency value alone.
  524.    *
  525.    * @param int x   where the pixel is in the image (we ignore this).
  526.    * @param int y   where the pixel is in the image (we ignore this).
  527.    * @param int rgb color encoded in an integer (stored; 0xaarrggbb).
  528.    * @return int integer encoding of the filtered result color.
  529.    */
  530.   public int filterRGB(int x, int y, int rgb)
  531.     {
  532.       /* extract the alpha (transparency) value */
  533.       int alpha = rgb & 0xff000000;
  534.  
  535.       /* return our color with their alpha */
  536.       return alpha | one_color;
  537.     }
  538.  
  539.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  540. }
  541. /*=========================== COPYRIGHT NOTICE ===========================
  542.  
  543. This file is part of the subArctic user interface toolkit.
  544.  
  545. Copyright (c) 1996 Scott Hudson and Ian Smith
  546. All rights reserved.
  547.  
  548. The subArctic system is freely available for most uses under the terms
  549. and conditions described in 
  550.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  551. and appearing in full in the lib/interactor.java source file.
  552.  
  553. The current release and additional information about this software can be 
  554. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  555.  
  556. ========================================================================*/
  557.